<!--
 * @Description: 
 * @Author: 张文韬
 * @Date: 2024-06-24 15:29:13
 * @LastEditTime: 2024-07-16 15:33:29
 * @LastEditors: 张文韬
 * @Reference: 
-->
<template>
  <div class="flex flex-justify-between">
    <div>
      <!-- <el-checkbox v-model="helpers.isAuto" label="自动" size="large" @change="autoPolicyChange" /> -->
      <el-checkbox v-model="helpers.isMany" label="单人单保" size="large" />
      <el-checkbox v-model="helpers.relationShow" label="投保关系" size="large" />
      <el-checkbox v-model="helpers.autoParse" label="自动加拼音" size="large" />
    </div>
    <div class="flex items-center">
      <!-- <upload @change="success" :model-value="fileList" /> -->
      <el-upload
        ref="fileUpload"
        v-model:file-list="fileList"
        :show-file-list="false"
        :headers="{Authorization: `Bearer ${token}`}"
        :action="ocrUrl"
        :on-success="ocrSuccess"
      >
        <el-dropdown @command="handleCommand">
          <el-button type="primary" class="ocr mr-3" disabled>
            OCR识别<el-icon class="el-icon--right"><arrow-down /></el-icon>
          </el-button>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="01">身份证</el-dropdown-item>
              <el-dropdown-item command="02">中国护照</el-dropdown-item>
              <el-dropdown-item command="03">国际护照</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        <!-- <el-button class="mr-3" type="primary" @click="ocr">身份证OCR识别</el-button> -->
      </el-upload>
      <el-button
        v-for="(button, index) in handleButtons"
        :key="button.text"
        :type="button.type"
        @click="tableHandleClick(index)"
      >{{ button.text }}</el-button>
    </div>
  </div>
  <div class="p-5px flex justify-between items-center">
    <div class="flex items-center">
      被保人列表
      <el-button class="ml-10px" type="primary" @click="changeAllCardType" link>证件类型切换</el-button>
    </div>
    <!-- ，实收保费：{{ 22.50 }} 元， 节省支出：{{ 7.50 }} 元 -->
    <span>保费总计：{{ tableData.length * props.itemPrice }} 元 </span>
  </div>
  <e-table 
    :data="tableData" 
    :columns="displayColumns" 
    :loading="loading"
    @select-all="handleSelectChange"
    @selection-change="handleSelectChange">
    <template #certificateType="{ scope }">
      <dict-tag :options="certificate_type" :value="scope.row.certificateType"></dict-tag>
    </template>
    <template #relationshipWithApplicant="{ scope }">
      <dict-tag :options="relationshipWithApplicant" :value="scope.row.relationshipWithApplicant"></dict-tag>
    </template>
    <template #benefit="{scope}">
      <el-button type="primary" @click="benefit(scope.row)" link>{{ scope.row.benefit&&scope.row.benefit.length > 0?'指定':'法定' }}</el-button>
    </template>
    <template #handleSlot="{scope}">
      <el-button type="warning" @click="edit(scope.row)" size="small">编辑</el-button>
      <!-- <el-button v-if="props.policyHolderType=='1'" type="primary" @click="setPolicyHolder(scope.row)" size="small">作为投保人</el-button> -->
      <el-button type="danger" @click="remove(scope.$index)" size="small">删除</el-button>
    </template>
  </e-table>
  <el-dialog
    v-model="dialogShow"
    :title="dialogTitle"
    :width="800"
    :before-close="closeDialog"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
  >
    <template v-if="dialogShow">
      <e-form
        v-if="dialogType == 'insurant-insert'||dialogType == 'insurant-edit'"
        class="mr-10px"
        ref="dialogForm"
        :form-options="formOptions"
        form-label-width="100px"
        :form-rules="formRules"
        :form-data-current="dialogFormCurrent"
        @nameChange="changeName"
        @cardTypeChange="changeCardType"
        @cardNumberChange="changeCardNumber"
        @birthChange="changeBirth"
      >
      </e-form>
      <template v-if="dialogType == 'list-analysis'">
        <div>名单规则：每行一个名单信息，空格分隔；如：测试 男 430421198703244918 1987-03-24 13912345678</div>
        <el-input class="mt-10px" input-style="height: 200px" v-model="analysisText" type="textarea"></el-input>
      </template>
      <template v-if="dialogType == 'analysis-result'">
        <div>
          <div>
            本次共复制有效数据 {{ parseData.successed.length + parseData.fails.length }} 行，其中:  成功分析出
            <span class="text-red">{{  parseData.successed.length }}</span> 行，失败 
            <span class="text-red">{{  parseData.fails.length }}</span> 行
          </div>
          <div v-if="parseData.fails.length > 0">
            <div>失败数据如下：</div>
            <div v-for="item in parseData.fails">{{ item }}</div>
          </div>
        </div>
      </template>
      <template v-if="dialogType == 'benefit'">
        <Benefit  />
      </template>
    </template>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleConfirm"> 确定 </el-button>
      </div>
    </template>
  </el-dialog>
  <!-- <UploadModal ref="uploadModalRef" /> -->
</template>

<script setup>

import { editFormOptions, editFormRules } from './form'
import columns from './columns'
import eTable from '@/components/e-table'
import idCardTool from "@/utils/id-card";
import useParse from "@/utils/parse-insurant";
import clipboard from '@/utils/clipboard'
import { ElMessage, ElMessageBox, dayjs } from 'element-plus';
import Benefit from '../Benefit/index.vue'
import { getFormatName, getPYOfName } from '@/utils/name'
import EForm from '/@/components/e-form/e-form.vue';
// import UploadModal from '../UploadModal/index.vue'
import { Session } from '/@/utils/storage';
import { useDict } from '/@/hooks/dict';

// 默认证件类型
let defaultCardType = '01'
let defaultMoney = 0

const props = defineProps({
  loading: {
    type: Boolean,
    default: false
  },
  policyHolderType: {
    type: String,
    default: ''
  },
  data: {
    type: Array,
    default: () => []
  },
  itemPrice: {
    type: Number,
    default: 0
  },
  columns: {
    type: Array,
    default: () => []
  },
  autoPolicy: {
    type: Boolean,
    default: true
  },
  isHasPolicy: {
    type: Boolean,
    default: false
  },
  isMany: {
    type: Boolean,
    default: false
  },
})

const emit = defineEmits(['get-draft', 'update:current', 'set-policy-holder', 'change-many'])

const { certificate_type, relationshipWithApplicant } = useDict('certificate_type', 'relationshipWithApplicant');


const dialogForm = ref()
const displayColumns = ref(columns)
const tableData = ref([])
const selectData = ref([])
const helpers = reactive({
  isAuto: props.autoPolicy,
  isMany: false,
  relationShow: false,
  autoParse: true,
})

const handleButtons = [
  { text: '粘贴名单', type: 'warning' },
  { text: '添加名单', type: 'success' },
  { text: '删除选中', type: 'danger' },
  { text: '复制名单', type: 'primary' },
  // { text: '草稿箱', type: 'info' }
]

const ocrType = ref ('1')
const fileUpload = ref (null)
const ocrUrl = computed(() => {
  if (ocrType.value == '01') {
    return import.meta.env.VITE_API_URL + '/admin/bbPolicy/ocr_id_card_head'
  }
  else if (ocrType.value == '02') {
    return import.meta.env.VITE_API_URL + '/admin/bbInsured/ocr_chinesePassport'
  }
  return import.meta.env.VITE_API_URL + '/admin/bbInsured/ocr_internationalPassport'
})

const handleCommand = (command) => {
  ocrType.value = command
  fileUpload.value.$el.querySelector('input').click()
}

const fileList = ref([])
// const uploadModalRef = ref()

const token = ref(Session.getToken())
const type = ref('')
const ocr = () => {
  console.log(11111);
  
};

const ocrSuccess = ({ code, data }) => {
  if (code == '1') {
    return ElMessage.error('识别失败')
  }
  if (ocrType.value == '01' && data) {
    dialogFormCurrent.value = {
      name: data.name.trim(),
      sexCode: data.sex == '男' ? 'M' : 'F',
      certificateType: '01',
      certificateNo: data.idNumber.trim(),
      birthday: idCardTool.getBirth(data.idNumber.trim()),
      age: idCardTool.getAge(data.idNumber.trim()),
      mobileTelephone: '',
      namePinYin : getPYOfName(getFormatName(data.name)).toLocaleUpperCase(),
    }
  } else  if (ocrType.value == '02' && data)  {
    const sex = data.sex.split('/')
    dialogFormCurrent.value = {
      name: data.name.trim(),
      sexCode: sex[1].trim(),
      certificateType: '02',
      certificateNo: data.passportNumber.trim(),
      birthday: dayjs(data.birthDate).format('YYYY-MM-DD'),
      age: birthToAgeDiff(data.birthDate),
      mobileTelephone: '',
      namePinYin: data.nameEn.replace(/,/g, ' ').trim()//getPYOfName(getFormatName(data.name)).toLocaleUpperCase(),
    }
  }  else  if (ocrType.value == '03' && data)  {
    dialogFormCurrent.value = {
      name: `${data.givenName.trim()} ${data.surname.trim()}`,
      sexCode: data.sex == 'Male'? 'M' : 'F',
      certificateType: '02',
      certificateNo: data.passportNumber.trim(),
      birthday: dayjs(data.birthDateYmd.trim()).format('YYYY-MM-DD'),
      age: birthToAgeDiff(data.birthDateYmd),
      mobileTelephone: '',
      namePinYin: data.nameEn.replace(/,/g, ' ').trim()//getPYOfName(data.name),
    }
  }
  changeCardType(ocrType.value)
  openDialog()
};

const autoPolicyChange = (type) => {
  emit('autoPolicyChange', type)
}

// dialog -------------------------------------------------------

// insurant：被保人  list-analysis: 只能名单分析   card-type
const dialogType = ref('insurant-insert') 
const dialogFormCurrent = ref(null)
const formOptions = ref([...editFormOptions])
const formRules = reactive({...editFormRules})
const dialogShow = ref(false)
const loadData = async () => {
	formOptions.value.forEach((item) => {
		if (item.key == 'certificateType') {
			item.options = certificate_type;
		}
    if (item.key == 'relationshipWithApplicant') {
			item.options = relationshipWithApplicant;
		}
	});
};
loadData();
const dialogTitle = computed(() => {
  if (dialogType.value == 'list-analysis') {
    return '智能名单分析'
  }
  else if (dialogType.value == 'analysis-result') {
    return '名单分析结果'
  }
  else if (dialogType.value == 'insurant-insert' || dialogType.value == 'insurant-edit') {
    return '被保人'
  }
  else if (dialogType.value == 'card-type') {
    return '证件类型'
  }
  else if (dialogType.value == 'benefit') {
    return '受益人列表'
  }
})

const changeName = (name, prop, obj) => {
  if (!name) return
  if (!obj && dialogForm.value) {
    obj = dialogForm.value.formData
  }
  // !RegExp(/[A-Za-z0-9]+/).test(name)
  if (!obj.namePinYin && helpers.autoParse) {
    obj.namePinYin = getPYOfName(getFormatName(name)).toLocaleUpperCase()
  }
  // else if ((RegExp(/[A-Za-z0-9]+/).test(name)) && helpers.autoParse) {
  //   obj.name = name.trim()
  // }
  else {
    obj.name = name.replace(/[A-Za-z0-9]+/g, '').trim()
  }
}

const changeCardType = (certificateType) => {
  const keys = ['age', 'birthday', 'sexCode']
  formOptions.value.map(o => {
    if (keys.includes(o.key)) {
      o.props.disabled = certificateType == '01'
    }
  })
}

const changeCardNumber = (certificateNo, config) => {
  const { certificateType } = dialogForm.value.formData
  if (certificateType != '01' || !idCardTool.isIdCard(certificateNo)) return
  dialogForm.value.formData.age = idCardTool.getAge(certificateNo)
  const gender = idCardTool.getSex(certificateNo)
  dialogForm.value.formData.sexCode = gender == '男' ? 'M' : 'F'
  dialogForm.value.formData.birthday = idCardTool.getBirth(certificateNo)
}

const changeBirth = (birthday) => {
  if (!birthday) return
  const formData = dialogForm.value.formData
  formData.age = dayjs().diff(dayjs(birthday), 'year')
}

const openDialog = (type = 'insurant-insert') => {
  dialogType.value = type
  dialogShow.value = true
}

const closeDialog = () => {
  dialogShow.value = false
}

const handleCancel = () => {
  dialogForm.value?.handleRefresh()
  closeDialog()
  dialogFormCurrent.value = null
  analysisText.value = ''
}

const handleConfirm = () => {
  if (dialogType.value == 'insurant-insert') {
    saveInsurant()
  }
  else if (dialogType.value == 'insurant-edit') {
    saveInsurant()
  }
  else if (dialogType.value == 'list-analysis') {
    saveAnalysisText()
  }
  else if (dialogType.value == 'analysis-result') {
    saveAnalysisResult()
  }
}

const saveInsurant = () => {
  dialogForm.value.handleValidate(validate => {
    const o = { ...dialogForm.value.formData }
    if (validate) {
      if (dialogType.value == 'insurant-insert') {
        tableData.value.push(o)
        // if (props.autoPolicy&&!props.isHasPolicy&&o.age >= 18) {
        //   emit('set-policy-holder', o)
        // }
      }
      else if (dialogType.value == 'insurant-edit') {
        tableData.value = tableData.value.map(t => t.certificateNo == o.certificateNo? o : t)
      }
      handleCancel()
    }
  })
}

const analysisText = ref('')
const parseData = reactive({
  successed: [],
  fails: []
})
const saveAnalysisText = () => {
  const { success, fails } = useParse(analysisText.value)
  console.log(success, fails);
  parseData.successed = success.map(o => ({...o, mobileTelephone: o.phone, sexCode: o.gender == '女'?'F':'M', premium: props.itemPrice}))
  parseData.fails = fails
  openDialog('analysis-result')
}

const saveAnalysisResult = () => {
  parseData.successed.map((o, i) => {
    changeName(o.name, null, o)
    tableData.value.push(o)
    // if (props.autoPolicy&&!props.isHasPolicy&&o.age >= 18) {
    //   emit('set-policy-holder', o)
    // }
  })
  // tableData.value = tableData.value.concat()
  const repeatArr = getRepeatArry(tableData.value, 'certificateNo')
  handleCancel()
  if (repeatArr.length > 0) {
    ElMessageBox.confirm(`检测出 ${repeatArr.length} 行证件重复数据，是否去重处理?`, '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
      center: true
    }).then(() => {
      const map = new Map()
      tableData.value = tableData.value.filter(o => !map.has(o.certificateNo) && map.set(o.certificateNo, o))
    })
  }
}

const addUniqueRule = () => {
  const rules = [{ 
    validator: (rule, value, callback) => {
      const obj = tableData.value.find(o => dialogType.value == 'insurant-insert'&&o.certificateNo == value)
      if (obj) {
        callback(new Error('该身份证号已存在'));
      } else {
        callback();
      }
    }, message: '该证件号码已存在', trigger: 'blur'
  }, { 
    validator: (rule, value, callback) => {
      const { certificateType } = dialogForm.value.formData
      if (certificateType == '01' && !(idCardTool.isIdCard(value))) {
        callback(new Error('身份证号码不符合规范'));
      } else {
        callback();
      }
    }, message: '身份证号格式错误', trigger: 'blur'
  }]
  formRules.certificateNo = editFormRules.certificateNo.concat(rules)
}

// table event -------------------------------------------------------
const changeAllCardType = () => {
  tableData.value.map(item => changeCardType(item))
}

const tableHandleClick = (index) => {
  switch (index) {
    case 0:
      listAnalysis()
      break;
    case 1:
      insert()
      break;
    case 2:
      removeSelected()
      break;
    case 3:
      copyList()
      break;
    // case 4:
    //   emit('get-draft')
    //   break;
  }
}

const insert = () => {
  console.log('insert');
  dialogFormCurrent.value = {
    id: dayjs().valueOf(),
    name: '',
    certificateType: defaultCardType,
    certificateNo: '',
    birthday: '',
    age: '',
    mobileTelephone: '',
    relationshipWithApplicant: '',
    premium: props.itemPrice
  }
  changeCardType(defaultCardType)
  openDialog()
}

const listAnalysis = () => {
  openDialog('list-analysis')
}

const removeSelected = () => {
  if (selectData.value.length == 0) {
    ElMessage.warning('未选择名单')
    return
  }
  const temp = selectData.value.map(o => o.id)
  tableData.value = tableData.value.filter(o => temp.indexOf(o.id) < 0)
}

const remove = (index) => {
  tableData.value.splice(index, 1)
}

const edit = (row) => {
  console.log(row);
  dialogFormCurrent.value = row
  changeCardType(row.certificateType)
  openDialog('insurant-edit')
}

const benefit = () => {
  openDialog('benefit')
}

const getTextFormTable = () => {
  return tableData.value.map(o => `${o.name||''} ${o.sexCode == 'M'?'男':'女'} ${o.certificateNo||''} ${o.birthday} ${o.age||''} ${o.mobileTelephone||''}`).join('\n')
}

const copyList = () => {
  if (tableData.value.length > 0) {
    const text = getTextFormTable()
    clipboard(text, '名单已复制到剪切板', '操作失败')
  }
  else {
    ElMessage.warning('列表暂无数据')
  }
}

const handleSelectChange = (e) =>  {
  selectData.value = e
}

const getData = async() => { 
  if (tableData.value.length < 1) {
    return ElMessage.warning('请添加被保人信息')
  }
  return tableData.value.map(o => ({...o, id: ''}))
}

const getRepeatArry = (arr, key) => {
  const repeatArr = []
  var obj = {};
  for (let i = 0; i < arr.length; i ++) {
    if (obj[arr[i][key]]) {
      repeatArr.push(i)
    } else {
      obj[arr[i][key]] = arr[i];
    }
  }
  return repeatArr;
}
const birthToAgeDiff = (birthDay) => {
  const birth = dayjs(birthDay);
  const now = dayjs();
  if(birth.valueOf()> now.valueOf()) return ''

  let years = now.year() - birth.year();
  let months = now.month() - birth.month();
  let days = now.date() - birth.date();

  if (days < 0) {
    months -= 1;
    days += dayjs(now).subtract(1, 'month').daysInMonth();
  }

  if (months < 0) {
    years -= 1;
    months += 12;
  }
  return years
};

// hook -------------------------------------------------------
watch(() => props.data, (val) => {
  tableData.value = val
})

watch(() => helpers.relationShow, (val) => {
  if (val) {
    displayColumns.value = columns
    formOptions.value = editFormOptions
  }
  else {
    displayColumns.value = columns.filter(o => o.label != '与投保人关系')
    formOptions.value = editFormOptions.filter(o => o.key != 'relationshipWithApplicant')
  }
}, { immediate: true })

watch(() => helpers.autoParse, (val) => {
  if (tableData.value.length > 0) {
    tableData.value.map(o => {
      changeName(o.name, undefined, o)
    })

  }
  
})

watch(() => helpers.isMany, (val) => {
  emit('change-many', val)
})

watch(() => props.isMany, (val) => {
  helpers.isMany = val
})

onMounted(() => {
  // addUniqueRule()
})

defineExpose({
  getData,
})

</script>
<style scoped>
.ocr.is-disabled {
  background-color: #2E5CF6;
}
</style>
